package fr.auzaiphe.commun.reseau;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import fr.auzaiphe.commun.Model;
import fr.auzaiphe.commun.View;
/**
 * Coté client du réseau.
 * Après la connexion au serveur cette classe sert d'envoyeur de packet au serveur.
 * @author Hugo
 * @author Jojo
 * @author Anthony
 */
public class ReseauClient
{
	private Socket socket;
	private ObjectOutputStream streamOut;
	private ReseauChatReceiver client;
	private Model model;
	private View view;
	private ReseauPacketHandler packetHandler;
	private String pseudo;

	/**
	 * Constructeur
	 * @param pServerName IP du serveur de chat
	 * @param pServerPort Port du serveur de chat
	 * @param pModel reference vers le model du joueur pour la gestion des paquets
	 */
	public ReseauClient( String pServerName, int pServerPort )
	{
		System.out.println("Establishing connection. Please wait ...");
		try
		{
			this.socket = new Socket(pServerName, pServerPort);
			System.out.println("Connected: " + this.socket);
		}
		catch (UnknownHostException uhe)
		{
			System.out.println("Host unknown: " + uhe.getMessage());
		}
		catch (IOException ioe)
		{
			System.out.println("Unexpected exception: " + ioe.getMessage());
		}
	}

	/**
	 * Initialisation du gestionnaire de paquet
	 * @param Model modele qui doit être en réseau
	 * @param View vue qui affiche l'etat du model
	 */
	public void initPacketHandler( Model pModel, View pView )
	{
		this.model = pModel;
		this.view = pView;
		this.packetHandler = new ReseauPacketHandler( this.model, this.view );
		try
		{
			this.start();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Envoie du paquet au serveur
	 * @param pPaquet paquet de n'importe quelle forme
	 */
	public void send( Packet pPaquet )
	{
		try
		{
			this.streamOut.writeObject( pPaquet );
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Demarre le client du chat
	 * Ouvre les flux d'entree et sortie et demarre de thread d'envoi.
	 * @throws IOException
	 */
	public void start() throws IOException
	{
		this.streamOut = new ObjectOutputStream( this.socket.getOutputStream() );
		this.client = new ReseauChatReceiver( this, this.socket, this.packetHandler );
		this.client.start();
	}

	/**
	 * Termine la connexion avec le serveur
	 */
	public void stop()
	{
		try
		{
			if (this.streamOut != null) this.streamOut.close();
			if (this.socket != null) this.socket.close();
		}
		catch (IOException ioe)
		{
			System.out.println("Error closing ...");
		}
		this.client.close();
		this.client.interrupt();
	}

	public ReseauChatReceiver getClient()
	{
		return this.client;
	}

	public Socket getSocket()
	{
		return this.socket;
	}

	public String getPseudo()
	{
		return this.pseudo;
	}

	public void setPseudo(String pseudo)
	{
		this.pseudo = pseudo;
	}
}
